home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / rhythmbox / plugins / artdisplay / CoverArtDatabase.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  8.8 KB  |  275 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import rhythmdb
  5. import rb
  6. import os
  7. import gtk
  8. import itertools
  9. import gobject
  10. from PodcastCoverArtSearch import PodcastCoverArtSearch
  11. from AmazonCoverArtSearch import AmazonCoverArtSearch
  12. from urllib import unquote
  13.  
  14. try:
  15.     import gio
  16.     if gio.pygio_version > (2, 15, 2):
  17.         from LocalCoverArtSearchGIO import LocalCoverArtSearch
  18. except:
  19.     from LocalCoverArtSearch import LocalCoverArtSearch
  20.  
  21. ART_SEARCHES_LOCAL = [
  22.     LocalCoverArtSearch]
  23. ART_SEARCHES_REMOTE = [
  24.     PodcastCoverArtSearch,
  25.     AmazonCoverArtSearch]
  26. OLD_ART_FOLDER = '~/.gnome2/rhythmbox/covers'
  27. ART_FOLDER = os.path.join(rb.user_cache_dir(), 'covers')
  28. ART_CACHE_EXTENSION_JPG = 'jpg'
  29. ART_CACHE_EXTENSION_PNG = 'png'
  30. ART_CACHE_FORMAT_JPG = 'jpeg'
  31. ART_CACHE_FORMAT_PNG = 'png'
  32. ART_CACHE_SETTINGS_JPG = {
  33.     'quality': '100' }
  34. ART_CACHE_SETTINGS_PNG = {
  35.     'compression': '9' }
  36.  
  37. class TicketSystem:
  38.     
  39.     def __init__(self):
  40.         self.counter = itertools.count()
  41.         self.hash = { }
  42.         self.dead = set()
  43.  
  44.     
  45.     def get(self, item):
  46.         ticket = self.counter.next()
  47.         self.hash.setdefault(item, set()).add(ticket)
  48.         return ticket
  49.  
  50.     
  51.     def bury(self, ticket):
  52.         
  53.         try:
  54.             self.dead.remove(ticket)
  55.             return True
  56.         except KeyError:
  57.             return False
  58.  
  59.  
  60.     
  61.     def forget(self, item, ticket):
  62.         
  63.         try:
  64.             self.hash[item].remove(ticket)
  65.             return True
  66.         except KeyError:
  67.             self.dead.remove(ticket)
  68.             return False
  69.  
  70.  
  71.     
  72.     def purge(self, item):
  73.         self.dead.update(self.hash.pop(item, set()))
  74.  
  75.     
  76.     def release(self, item, ticket):
  77.         
  78.         try:
  79.             self.dead.update(self.hash.pop(item) - set([
  80.                 ticket]))
  81.             return True
  82.         except KeyError:
  83.             self.dead.remove(ticket)
  84.             return False
  85.  
  86.  
  87.  
  88.  
  89. class CoverArtDatabase(object):
  90.     
  91.     def __init__(self):
  92.         self.ticket = TicketSystem()
  93.  
  94.     
  95.     def build_art_cache_filename(self, db, entry, extension):
  96.         artist = db.entry_get(entry, rhythmdb.PROP_ARTIST)
  97.         album = db.entry_get(entry, rhythmdb.PROP_ALBUM)
  98.         art_folder = os.path.expanduser(ART_FOLDER)
  99.         old_art_folder = os.path.expanduser(OLD_ART_FOLDER)
  100.         if not os.path.exists(art_folder) and os.path.exists(old_art_folder):
  101.             parent = os.path.dirname(os.path.abspath(art_folder))
  102.             if not os.path.exists(parent):
  103.                 os.makedirs(parent)
  104.             
  105.             os.rename(old_art_folder, art_folder)
  106.         
  107.         if not os.path.exists(art_folder):
  108.             os.makedirs(art_folder)
  109.         
  110.         return art_folder + '/%s - %s.%s' % (artist.replace('/', '-'), album.replace('/', '-'), extension)
  111.  
  112.     
  113.     def engines(self, blist):
  114.         for Engine in ART_SEARCHES_LOCAL:
  115.             yield (Engine(), Engine.__name__, False)
  116.         
  117.         for Engine in ART_SEARCHES_REMOTE:
  118.             if Engine.__name__ not in blist:
  119.                 yield (Engine(), Engine.__name__, True)
  120.                 continue
  121.         
  122.  
  123.     
  124.     def set_pixbuf_from_uri(self, db, entry, uri, callback):
  125.         
  126.         def loader_cb(data):
  127.             self.set_pixbuf(db, entry, self.image_data_load(data), callback)
  128.  
  129.         l = rb.Loader()
  130.         l.get_url(str(uri), loader_cb)
  131.  
  132.     
  133.     def set_pixbuf(self, db, entry, pixbuf, callback):
  134.         if entry is None or pixbuf is None:
  135.             return None
  136.         if pixbuf.get_has_alpha():
  137.             art_location = self.build_art_cache_filename(db, entry, ART_CACHE_EXTENSION_PNG)
  138.             art_cache_format = ART_CACHE_FORMAT_PNG
  139.             art_cache_settings = ART_CACHE_SETTINGS_PNG
  140.         else:
  141.             art_location = self.build_art_cache_filename(db, entry, ART_CACHE_EXTENSION_JPG)
  142.             art_cache_format = ART_CACHE_FORMAT_JPG
  143.             art_cache_settings = ART_CACHE_SETTINGS_JPG
  144.         self.ticket.purge(entry)
  145.         pixbuf.save(art_location, art_cache_format, art_cache_settings)
  146.         callback(entry, pixbuf, art_location)
  147.         for Engine in ART_SEARCHES_LOCAL:
  148.             
  149.             try:
  150.                 Engine().save_pixbuf(db, entry, pixbuf)
  151.             continue
  152.             except AttributeError:
  153.                 continue
  154.             
  155.  
  156.         
  157.  
  158.     
  159.     def cancel_get_pixbuf(self, entry):
  160.         self.ticket.purge(entry)
  161.  
  162.     
  163.     def get_pixbuf(self, db, entry, callback):
  164.         if entry is None:
  165.             callback(entry, None, None)
  166.             return None
  167.         if not db.entry_get(entry, rhythmdb.PROP_ARTIST):
  168.             pass
  169.         st_artist = _('Unknown')
  170.         if not db.entry_get(entry, rhythmdb.PROP_ALBUM):
  171.             pass
  172.         st_album = _('Unknown')
  173.         for char in [
  174.             '"']:
  175.             st_artist = st_artist.replace(char, '')
  176.             st_album = st_album.replace(char, '')
  177.         
  178.         rb.Coroutine(self.image_search, db, st_album, st_artist, entry, callback).begin()
  179.  
  180.     
  181.     def image_search(self, plexer, db, st_album, st_artist, entry, callback):
  182.         art_location_jpg = self.build_art_cache_filename(db, entry, ART_CACHE_EXTENSION_JPG)
  183.         art_location_png = self.build_art_cache_filename(db, entry, ART_CACHE_EXTENSION_PNG)
  184.         blist_location = self.build_art_cache_filename(db, entry, 'rb-blist')
  185.         art_location = None
  186.         if os.path.exists(art_location_jpg):
  187.             art_location = art_location_jpg
  188.         
  189.         if os.path.exists(art_location_png):
  190.             art_location = art_location_png
  191.         
  192.         if art_location:
  193.             self.ticket.purge(entry)
  194.             pixbuf = gtk.gdk.pixbuf_new_from_file(art_location)
  195.             callback(entry, pixbuf, art_location)
  196.             return None
  197.         blist = self.read_blist(blist_location)
  198.         ticket = self.ticket.get(entry)
  199.         for engine, engine_name, engine_remote in self.engines(blist):
  200.             plexer.clear()
  201.             engine.search(db, entry, plexer.send())
  202.             while True:
  203.                 yield None
  204.                 art_location
  205.                 (engine, entry, results) = (_,)
  206.                 if not results:
  207.                     break
  208.                 
  209.                 for url in engine.get_best_match_urls(results):
  210.                     if str(url) == '':
  211.                         print 'got empty url from engine %s.' % engine
  212.                         continue
  213.                     
  214.                     l = rb.Loader()
  215.                     yield l.get_url(str(url), plexer.send())
  216.                     (data,) = (_,)
  217.                     pixbuf = self.image_data_load(data)
  218.                     if pixbuf:
  219.                         if self.ticket.release(entry, ticket):
  220.                             callback(entry, pixbuf, uri)
  221.                         
  222.                         self.write_blist(blist_location, blist)
  223.                         return None
  224.                 
  225.                 if not engine.search_next():
  226.                     break
  227.                 
  228.                 if self.ticket.bury(ticket):
  229.                     self.write_blist(blist_location, blist)
  230.                     return None
  231.                 continue
  232.                 self.ticket.bury(ticket)
  233.             if self.ticket.bury(ticket):
  234.                 self.write_blist(blist_location, blist)
  235.                 return None
  236.         
  237.         if self.ticket.forget(entry, ticket):
  238.             callback(entry, None, None)
  239.         
  240.         self.write_blist(blist_location, blist)
  241.  
  242.     
  243.     def read_blist(self, blist_location):
  244.         if os.path.exists(blist_location):
  245.             return [ line.strip() for line in file(blist_location) ]
  246.         return []
  247.  
  248.     
  249.     def write_blist(self, blist_location, blist):
  250.         if blist:
  251.             blist_file = file(blist_location, 'w')
  252.             blist_file.writelines(blist)
  253.             blist_file.close()
  254.         elif os.path.exists(blist_location):
  255.             os.unlink(blist_location)
  256.         
  257.  
  258.     
  259.     def image_data_load(self, data):
  260.         if data and len(data) >= 1000:
  261.             pbl = gtk.gdk.PixbufLoader()
  262.             
  263.             try:
  264.                 if pbl.write(data) and pbl.close():
  265.                     return pbl.get_pixbuf()
  266.             except gobject.GError:
  267.                 pass
  268.             except:
  269.                 None<EXCEPTION MATCH>gobject.GError
  270.             
  271.  
  272.         None<EXCEPTION MATCH>gobject.GError
  273.  
  274.  
  275.